package config

import (
	"fmt"
	"log"
	"os"
	"path/filepath"

	"gopkg.in/yaml.v2"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// 全局变量
var (
	DB     *gorm.DB // 数据库连接实例
	config *Config  // 全局配置实例
)

// Config 配置文件结构体
// 用于存储应用程序的所有配置信息
type Config struct {
	App      AppConfig      `yaml:"app"`      // 应用程序基本配置
	JWT      JWTConfig      `yaml:"jwt"`      // JWT认证配置
	Database DatabaseConfig `yaml:"database"` // 数据库配置
	API      APIConfig      `yaml:"api"`      // API配置
}

// AppConfig 应用程序基本配置
type AppConfig struct {
	Name string `yaml:"name"` // 应用名称
	Port int    `yaml:"port"` // 服务端口
	Env  string `yaml:"env"`  // 运行环境
}

// JWTConfig JWT认证配置
type JWTConfig struct {
	SecretKey   string `yaml:"secret_key"`   // JWT密钥
	ExpireHours int    `yaml:"expire_hours"` // 令牌过期时间（小时）
	Issuer      string `yaml:"issuer"`       // 令牌发行者
}

// DatabaseConfig 数据库配置
type DatabaseConfig struct {
	Type      string `yaml:"type"`       // 数据库类型
	Host      string `yaml:"host"`       // 数据库主机地址
	Port      int    `yaml:"port"`       // 数据库端口
	Username  string `yaml:"username"`   // 数据库用户名
	Password  string `yaml:"password"`   // 数据库密码
	DBName    string `yaml:"dbname"`     // 数据库名称
	Charset   string `yaml:"charset"`    // 字符集
	ParseTime bool   `yaml:"parse_time"` // 是否解析时间
	Loc       string `yaml:"loc"`        // 时区
}

// APIConfig API配置
type APIConfig struct {
	Version string `yaml:"version"` // API版本
	Prefix  string `yaml:"prefix"`  // API前缀
}

// InitConfig 初始化配置和数据库
// 功能：
// 1. 读取配置文件
// 2. 解析配置信息
// 3. 初始化数据库连接
// 返回：
//   - error: 初始化过程中的错误
func InitConfig() error {
	// 读取配置文件
	configPath := filepath.Join("config", "config.yaml")
	data, err := os.ReadFile(configPath)
	if err != nil {
		return fmt.Errorf("读取配置文件失败: %v", err)
	}

	// 解析配置
	config = &Config{}
	if err := yaml.Unmarshal(data, config); err != nil {
		return fmt.Errorf("解析配置文件失败: %v", err)
	}

	// 初始化数据库连接
	if err := initDatabase(); err != nil {
		return fmt.Errorf("初始化数据库失败: %v", err)
	}

	return nil
}

// initDatabase 初始化数据库连接
// 功能：
// 1. 构建数据库连接字符串
// 2. 建立数据库连接
// 3. 验证连接是否成功
// 返回：
//   - error: 连接过程中的错误
func initDatabase() error {
	// 构建DSN连接字符串
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=%v&loc=%s",
		config.Database.Username,
		config.Database.Password,
		config.Database.Host,
		config.Database.Port,
		config.Database.DBName,
		config.Database.Charset,
		config.Database.ParseTime,
		config.Database.Loc,
	)

	var err error
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		return fmt.Errorf("连接mysql数据库失败: %v", err)
	}

	log.Println("连接mysql成功")
	return nil
}

// GetConfig 获取全局配置实例
// 返回：
//   - *Config: 配置实例
func GetConfig() *Config {
	return config
}

// GetAPIPath 获取完整的API路径
// 参数：
//   - path: API路径
//
// 返回：
//   - string: 完整的API路径
func GetAPIPath(path string) string {
	return fmt.Sprintf("%s/%s%s", config.API.Prefix, config.API.Version, path)
}

// GetDatabaseType 获取数据库类型
// 返回：
//   - string: 数据库类型
func GetDatabaseType() string {
	return config.Database.Type
}

// 调试指南：
// 1. 配置文件测试：
//    - 确保config.yaml文件存在且格式正确
//    - 检查所有必需的配置项是否已设置
//    - 验证配置值是否符合预期
//
// 2. 数据库连接测试：
//    - 检查数据库服务是否运行
//    - 验证数据库凭据是否正确
//    - 确认数据库名称是否存在
//
// 3. 常见问题排查：
//    - 配置文件读取失败：检查文件路径和权限
//    - 配置解析错误：检查YAML格式是否正确
//    - 数据库连接失败：检查网络连接和凭据
//    - 全局变量未初始化：确保InitConfig被正确调用
